﻿using System;
using System.Diagnostics;
using System.Threading;

namespace BoatNGoat.Server
{
    public abstract class Host
    {        
        private readonly TimeSpan _ticksPerGameTick;
        private bool _exit = false;

        protected Host(int gameTicksPerSecond)
        {
            _ticksPerGameTick = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / gameTicksPerSecond);
        }

        private readonly Stopwatch _timer = new Stopwatch();


        public void Run()
        {            
            
            ServerTime serverTime = new ServerTime();
            _timer.Start();
            TimeSpan previousTotalElapsed = TimeSpan.Zero;
            TimeSpan sleepTicks = TimeSpan.Zero;
            while (!_exit)
            {
                TimeSpan totalElapsed = _timer.Elapsed;
                serverTime.Update(totalElapsed, totalElapsed - previousTotalElapsed, sleepTicks < TimeSpan.Zero);
                previousTotalElapsed = totalElapsed;
                
                Update(serverTime);

                sleepTicks = (_ticksPerGameTick + previousTotalElapsed) - _timer.Elapsed;
                if (sleepTicks > TimeSpan.Zero)
                {
                    Thread.Sleep((int)Math.Round((double)sleepTicks.Ticks / TimeSpan.TicksPerMillisecond));
                }
            }            
        }

        public abstract void Update(ServerTime serverTime);
        public abstract void Init();

        public void Stop()
        {
            _exit = true;
        }
    }
}
